// set standard header
#pragma once
#ifndef _SET_
#define _SET_
#ifndef RC_INVOKED
#include <xtree>

#ifdef _MSC_VER
 #pragma pack(push,_CRT_PACKING)
 #pragma warning(push,3)
#endif  /* _MSC_VER */
_STD_BEGIN

		// TEMPLATE CLASS _Tset_traits
template<class _Kty,	// key/value type
	class _Pr,	// comparator predicate type
	class _Alloc,	// actual allocator type (should be value allocator)
	bool _Mfl>	// true if multiple equivalent keys are permitted
	class _Tset_traits
		: public _CONTAINER_BASE_AUX_ALLOC<_Alloc>
	{	// traits required to make _Tree behave like a set
public:
	typedef _Kty key_type;
	typedef _Kty value_type;
	typedef _Pr key_compare;
	typedef typename _Alloc::template rebind<value_type>::other
		allocator_type;

	typedef typename allocator_type::const_pointer _ITptr;
	typedef typename allocator_type::const_reference _IReft;

	enum
		{	// make multi parameter visible as an enumeration constant
		_Multi = _Mfl};

	_Tset_traits(_Pr _Parg, _Alloc _Al)
		: _CONTAINER_BASE_AUX_ALLOC<_Alloc>(_Al), comp(_Parg)
		{	// construct with specified comparator
		}

	typedef key_compare value_compare;

	static const _Kty& _Kfn(const value_type& _Val)
		{	// extract key from element value
		return (_Val);
		}

	_Pr comp;	// the comparator predicate for keys
	};

		// TEMPLATE CLASS set
template<class _Kty,
	class _Pr = less<_Kty>,
	class _Alloc = allocator<_Kty> >
	class set
		: public _Tree<_Tset_traits<_Kty, _Pr, _Alloc, false> >
	{	// ordered red-black tree of key values, unique keys
public:
	typedef set<_Kty, _Pr, _Alloc> _Myt;
	typedef _Tree<_Tset_traits<_Kty, _Pr, _Alloc, false> > _Mybase;
	typedef _Kty key_type;
	typedef _Pr key_compare;
	typedef typename _Mybase::value_compare value_compare;
	typedef typename _Mybase::allocator_type allocator_type;
	typedef typename _Mybase::size_type size_type;
	typedef typename _Mybase::difference_type difference_type;
	typedef typename _Mybase::pointer pointer;
	typedef typename _Mybase::const_pointer const_pointer;
	typedef typename _Mybase::reference reference;
	typedef typename _Mybase::const_reference const_reference;
	typedef typename _Mybase::iterator iterator;
	typedef typename _Mybase::const_iterator const_iterator;
	typedef typename _Mybase::reverse_iterator reverse_iterator;
	typedef typename _Mybase::const_reverse_iterator
		const_reverse_iterator;
	typedef typename _Mybase::value_type value_type;

	set()
		: _Mybase(key_compare(), allocator_type())
		{	// construct empty set from defaults
		}

	explicit set(const key_compare& _Pred)
		: _Mybase(_Pred, allocator_type())
		{	// construct empty set from comparator
		}

	set(const key_compare& _Pred, const allocator_type& _Al)
		: _Mybase(_Pred, _Al)
		{	// construct empty set from comparator and allocator
		}

	template<class _Iter>
		set(_Iter _First, _Iter _Last)
		: _Mybase(key_compare(), allocator_type())
		{	// construct set from [_First, _Last), defaults
		_DEBUG_RANGE(_First, _Last);
		for (; _First != _Last; ++_First)
			this->insert(*_First);
		}

	template<class _Iter>
		set(_Iter _First, _Iter _Last,
			const key_compare& _Pred)
		: _Mybase(_Pred, allocator_type())
		{	// construct set from [_First, _Last), comparator
		_DEBUG_RANGE(_First, _Last);
		for (; _First != _Last; ++_First)
			this->insert(*_First);
		}

	template<class _Iter>
		set(_Iter _First, _Iter _Last,
			const key_compare& _Pred, const allocator_type& _Al)
		: _Mybase(_Pred, _Al)
		{	// construct set from [_First, _Last), defaults, and allocator
		_DEBUG_RANGE(_First, _Last);
		for (; _First != _Last; ++_First)
			this->insert(*_First);
		}

 #if _HAS_STRICT_CONFORMANCE
	void erase(const_iterator _Where)
		{	// erase element at _Where
		_Mybase::erase(_Where);
		}

	size_type erase(const key_type& _Keyval)
		{	// erase and count all that match _Keyval
		return (_Mybase::erase(_Keyval));
		}

	void erase(const_iterator _First, const_iterator _Last)
		{	// erase [_First, _Last)
		_Mybase::erase(_First, _Last);
		}
 #endif /* _HAS_STRICT_CONFORMANCE */



	};

	// set implements a performant swap
template<class _Kty, class _Pr, class _Alloc>
	class _Move_operation_category<set<_Kty, _Pr, _Alloc> >
	{
	public:
		typedef _Swap_move_tag _Move_cat;
	};

template<class _Kty,
	class _Pr,
	class _Alloc> inline
	void swap(set<_Kty, _Pr, _Alloc>& _Left,
		set<_Kty, _Pr, _Alloc>& _Right)
	{	// swap _Left and _Right sets
	_Left.swap(_Right);
	}

		// TEMPLATE CLASS multiset
template<class _Kty,
	class _Pr = less<_Kty>,
	class _Alloc = allocator<_Kty> >
	class multiset
		: public _Tree<_Tset_traits<_Kty, _Pr, _Alloc, true> >
	{	// ordered red-black tree of key values, non-unique keys
public:
	typedef multiset<_Kty, _Pr, _Alloc> _Myt;
	typedef _Tree<_Tset_traits<_Kty, _Pr, _Alloc, true> > _Mybase;
	typedef _Kty key_type;
	typedef _Pr key_compare;
	typedef typename _Mybase::value_compare value_compare;
	typedef typename _Mybase::allocator_type allocator_type;
	typedef typename _Mybase::size_type size_type;
	typedef typename _Mybase::difference_type difference_type;
	typedef typename _Mybase::pointer pointer;
	typedef typename _Mybase::const_pointer const_pointer;
	typedef typename _Mybase::reference reference;
	typedef typename _Mybase::const_reference const_reference;
	typedef typename _Mybase::iterator iterator;
	typedef typename _Mybase::const_iterator const_iterator;
	typedef typename _Mybase::reverse_iterator reverse_iterator;
	typedef typename _Mybase::const_reverse_iterator
		const_reverse_iterator;
	typedef typename _Mybase::value_type value_type;

	multiset()
		: _Mybase(key_compare(), allocator_type())
		{	// construct empty set from defaults
		}

	explicit multiset(const key_compare& _Pred)
		: _Mybase(_Pred, allocator_type())
		{	// construct empty set from comparator
		}

	multiset(const key_compare& _Pred, const allocator_type& _Al)
		: _Mybase(_Pred, _Al)
		{	// construct empty set from comparator and allocator
		}

	template<class _Iter>
		multiset(_Iter _First, _Iter _Last)
		: _Mybase(key_compare(), allocator_type())
		{	// construct set from [_First, _Last)
		_DEBUG_RANGE(_First, _Last);
		for (; _First != _Last; ++_First)
			this->insert(*_First);
		}

	template<class _Iter>
		multiset(_Iter _First, _Iter _Last,
			const key_compare& _Pred)
		: _Mybase(_Pred, allocator_type())
		{	// construct set from [_First, _Last), comparator
		_DEBUG_RANGE(_First, _Last);
		for (; _First != _Last; ++_First)
			this->insert(*_First);
		}

	template<class _Iter>
		multiset(_Iter _First, _Iter _Last,
			const key_compare& _Pred, const allocator_type& _Al)
		: _Mybase(_Pred, _Al)
		{	// construct set from [_First, _Last), comparator, and allocator
		_DEBUG_RANGE(_First, _Last);
		for (; _First != _Last; ++_First)
			this->insert(*_First);
		}

 #if _HAS_STRICT_CONFORMANCE
	void erase(const_iterator _Where)
		{	// erase element at _Where
		_Mybase::erase(_Where);
		}

	size_type erase(const key_type& _Keyval)
		{	// erase and count all that match _Keyval
		return (_Mybase::erase(_Keyval));
		}

	void erase(const_iterator _First, const_iterator _Last)
		{	// erase [_First, _Last)
		_Mybase::erase(_First, _Last);
		}
 #endif /* _HAS_STRICT_CONFORMANCE */

	iterator insert(const value_type& _Val)
		{	// insert a key value
		return (_Mybase::insert(_Val).first);
		}

	iterator insert(const_iterator _Where, const value_type& _Val)
		{	// insert a key value, with hint
		return (_Mybase::insert(_Where, _Val));
		}

	template<class _Iter>
		void insert(_Iter _First, _Iter _Last)
		{	// insert [_First, _Last)

 #if _HAS_ITERATOR_DEBUGGING
		_DEBUG_RANGE(_First, _Last);
 #endif /* _HAS_ITERATOR_DEBUGGING */

		for (; _First != _Last; ++_First)
			this->insert(*_First);
		}
	};

	// multiset implements a performant swap
template<class _Kty, class _Pr, class _Alloc>
	class _Move_operation_category<multiset<_Kty, _Pr, _Alloc> >
	{
	public:
		typedef _Swap_move_tag _Move_cat;
	};

template<class _Kty,
	class _Pr,
	class _Alloc> inline
	void swap(multiset<_Kty, _Pr, _Alloc>& _Left,
		multiset<_Kty, _Pr, _Alloc>& _Right)
	{	// swap _Left and _Right multisets
	_Left.swap(_Right);
	}

 #if _HAS_TRADITIONAL_STL
 #define __set__	set
 #define __multiset__	multiset
 #endif /* _HAS_TRADITIONAL_STL */

_STD_END
#ifdef _MSC_VER
 #pragma warning(pop)
 #pragma pack(pop)
#endif  /* _MSC_VER */

#endif /* RC_INVOKED */
#endif /* _SET_ */

/*
 * Copyright (c) 1992-2007 by P.J. Plauger.  ALL RIGHTS RESERVED.
 * Consult your license regarding permissions and restrictions.
 V5.03:0009 */
